package com.github.hgkmail.hello.cmd;

import com.github.hgkmail.hello.netty.ChatServerHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

//https://blog.csdn.net/qq_37936542/article/details/88693866
public class HelloNettyServer {

    private static final Logger logger = LoggerFactory.getLogger(HelloNettyServer.class);

    private int port;

    public HelloNettyServer(int port) {
        this.port = port;
    }

    public void start() {

        // 创建服务类
        ServerBootstrap sb = new ServerBootstrap();

        // 创建boss和woker
        NioEventLoopGroup boss = new NioEventLoopGroup();
        NioEventLoopGroup woker = new NioEventLoopGroup();

        try {
            // 设置线程池
            sb.group(boss, woker);

            // 设置channel工厂
            sb.channel(NioServerSocketChannel.class);

            // 设置管道
            sb.childHandler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel ch) throws Exception {
                    ch.pipeline().addLast(new HttpServerCodec());// websocket基于http协议，需要HttpServerCodec
                    ch.pipeline().addLast(new HttpObjectAggregator(65535)); // http消息组装，消息长度不能超过64K
                    ch.pipeline().addLast(new WebSocketServerProtocolHandler("/ws")); // websocket通信支持
                    ch.pipeline().addLast(new ChatServerHandler()); // 自定义处理器
                }
            });

            // 服务器异步创建绑定
            ChannelFuture cf = sb.bind(port).sync();

            // 等待服务端关闭
            cf.channel().closeFuture().sync();

        } catch (Exception e) {
            logger.warn("聊天服务发生异常: {}", e);
        } finally {
            boss.shutdownGracefully();
            woker.shutdownGracefully();
        }
    }

    /**
     * server启动
     * @param args
     */
    public static void main(String[] args) {
        new HelloNettyServer(9010).start();
    }

}
